Introducción


Es conveniente aprender lo básico sobre programación y, entre otros sitios, lo podemos hacer siguiendo los siguientes enlaces.

Descargas


Todos los ejemplos están accesibles desde el repositorio en github

PLAYLIST


Lista de reproducción con todos los vídeos demostrativos del funcionamiento de los ejemplos

Librerías

Aquí podéis descargar las librerías que iremos necesitando durante el curso.
Librería para el uso del keypad.
Librería para el uso de la LCD.
Librería para la conversión a datos tipo String y su manejo.
Librería para el uso del sensor de humedad y temperatura DHT11
Librería para el control de tiempos (necesaria para el RTC).
Librería para el manejo del RTC DS1302.

Enlaces de interés


Ejemplos de aplicación

Introductorios

_001_Parpadeo de dos LEDs


Video _001



  • Esquema
E001.jpg
Se trata de un sencillo ejemplo en el que alternativamente parpadean el LED interno conectado al pin 13 y un LED externo montado en la protoboard con retardos de un segundo.
  • Código
// Parpadeo de dos LED el interno del pin 13 y uno externo conectado al pin 12
int led13 = 13;
int led12 = 12;
// the setup routine runs once when you press reset:
void setup() {
// Configuramos los dos pines como salida
pinMode(led13, OUTPUT);
pinMode(led12, OUTPUT);
}
void loop() {
digitalWrite(led13, HIGH); //LED interno encendido
digitalWrite(led12, LOW); //LED externo apagado
delay(1000); // wait for a second
digitalWrite(led13, LOW); //LED interno apagado
digitalWrite(led12, HIGH); //LED externo encendido
delay(1000); // wait for a second
}

_002_HolaMundo



Video _002

  • Esquema

E002.jpg
Típico ejemplo Hola Mundo en el que se hace parpadear un LED conectado al pin 12.
  • Código
void setup() //Configuraciones
{
  pinMode(12,OUTPUT); //Hace pin 12 salida
}
void loop() //Bucle
{
  digitalWrite(12,HIGH); //Enciende LED
  delay(500); //Retardo medio segundo
  digitalWrite(12,LOW); //Apaga LED
  delay(500);
}

_003_PWMBasico



Video _003


  • Esquema

E003.jpg


Introducción al concepto de PWM

Con este ejemplo queremos demostrar el uso de salida analógica PWM. La modulación por ancho de pulso, o PWM, es una técnica para obtener resultados analógicos con medios digitales. El control digital se utiliza para crear una onda cuadrada que conmuta entre 0V (OFF) y 5V (ON). La técnica consiste en ajustar los tiempos que la señal está en ON y en OFF. La duración o tiempo en ON se denomina ancho de pulso. Para obtener valores variables (analógicos), se cambia o modular el ancho de pulso. El Duty Cycle es el porcentaje de tiempo que la señal está en ON. Gráficamente se representa así.
E003Duty.jpg

Descripción del bucle for

Es una instrucción repetitiva que permite repetir una serie de veces la ejecución de unas líneas de código bien un número determinado de veces o bien hasta que se cumpla una determinada condición lógica o aritmética.
De una forma genérica, a las instrucciones o sentencias repetitivas o cíclicas se les denomina bucles.
La instrucción for permite repetir una cantidad conocida y exacta de veces la ejecución de una instrucción simple o compuesta. Su sintaxis general es:
for ([<inicializacion>] ; [<condicion>] ; [<incremento>])
{
instrucción o instrucciones simples o compuestas;
};
Pudiendo en inicializacion representar varias variables de control iniciadas con sus correspondientes valores y separadas por comas.
Condición representa una expresión booleana que si se omite se supone verdadera.
Incremento es una o más expresiones separadas por comas cuyos valores evolucionan en el sentido que se cumpla la condición.

Uso de analogWrite()

En el gráfico anterior, las líneas verdes representan un período de tiempo regular o período que es la inversa de la frecuencia PWM. En otras palabras, con una frecuencia PWM de 500 Hz, las líneas verdes medirían 2 milisegundos cada uno. Una llamada a analogWrite () es en una escala de 0 - 255, de tal manera que analogWrite (255) solicita un ciclo de trabajo del 100% (siempre encendido), y analogWrite (127) es un ciclo de trabajo del 50% (en la mitad del tiempo) para ejemplo.
  • Código
int Pin9 = 9; //Nombramos Pin 9
void setup() //Configuraciones
{
  //No hay que hacer ninguna configuración para este ejemplo
}
void loop() //Bucle infinito
{
  for(int i=0; i<=255; i=i+3)
  {
  analogWrite(Pin9,i); //Enciende progresivamente el LED
  delay(40);
  }
  for(int i=255; i>=0; i=i-3)
  {
  analogWrite(Pin9,i); //Apaga progresivamente el LED
  delay(40);
  }
}

_004_EntradaDigital



Video _004

  • Esquema

E004.jpg


Ejemplo en el que un LED permanece encendido hasta que accionamos un pulsador, y estará apagado mientras mantenemos accionado dicho pulsador.

Instrucciones condicionales

Una característica muy poderosa de cualquier programa es la capacidad que tiene de tomar decisiones, es decir, que al comparar dos alternativas diferentes pueda tomar una decisión basada en la evaluación de alguna condición impuesta por el programador. Es por tanto necesario que un lenguaje de programación tenga instrucciones que permitan formar estas condiciones e instrucciones que pueden evaluarlas.
El formato general de una instrucción condicional genérica es:
Instrucción condicional (condición)
    si condición cierta
    {
    grupo de instrucciones para verdadero
    }
    si condición falsa
   {
   grupo de instrucciones para falso
   }
Observamos cuatro partes bien diferenciadas:
  1. La propia instrucción condicional
  2. La condición
  3. El grupo de instrucciones para verdadero
  4. El grupo de instrucciones para falso.
Cuando el programa evalúa una condición solo puede hacerlo de dos maneras: o la condición es cierta o verdadera (true) o la condición es falsa (false), lo que dependerá del valor que tenga asignado o que se haya capturado para la variable que está en la condición, y dependiendo del resultado de la evaluación se ejecutarán las instrucciones de la parte cierta o las de la parte falsa de la condición.
En general todas las condiciones simples se forman con variables, operadores de relación o relacionales, constantes o variable. Una condición simple se define como el conjunto de variables y/o constantes unidas por los llamados operadores relacionales.
Debemos tener especial cuidado con el operador de igualdad (=) y el operador relacional de comparación por igualdad (==), es decir:
Dato=10 se asigna el valor 10 a la variable dato.
Dato==10 se compara el valor de dato con el numero 10.
Solo este ultimo formato es valido dentro de una condición, en una instrucción condicional.

La instrucción if

Sin duda es la más usada de todas y que vamos a analizar seguidamente.
Sintaxis
if (condición)
   {
   instrucciones para verdadero;
   }
   else
   {
   instrucciones para falso;
   }
Proceso de ejecución
  1. Se evalúa la condición, que puede ser una expresión numérica, relacional o lógica.
  2. Si el resultado de evaluar la condición es verdadero se ejecutan instrucciones para verdadero.
  3. Si el resultado de evaluar la condición es falso (resultado cero) se ejecutan instrucciones para falso, siempre que se haya especificado la clausula else.
  4. Si el resultado de evaluar la condición es falso y se ha omitido la clausula else se ignora la sentencia de grupo de instrucciones para verdadero.
  5. En cualquiera de los casos la ejecución del programa continúa por la siguiente sentencia ejecutable.
Debemos tener muy presentes las siguientes observaciones:
  1. Donde van y donde no van los puntos y comas
  2. La condición va entre paréntesis
  3. Si un if no tiene un grupo de instrucciones para falso se omite el else, y la llave antes de else si terminaría con punto y coma.
  • Código
int pulsadorE=2;  //Indicamos el pin al que va el pulsador de entrada
int ledS=9; //Pin donde se encuentra el LED de salida
 
void setup(){ // Configuraciones
  pinMode(pulsadorE, INPUT); //Configurar pin 2 como entrada
  pinMode(ledS,OUTPUT); //Configurar pin 9 como salida
}
void loop(){
 //Condicional para saber estado del pulsador
 if (digitalRead(pulsadorE)==HIGH) //Pulsador NO accionado
   {
   digitalWrite(ledS,HIGH); //Enciende el LED
   }
   else //Pulsador accionado
   {
   digitalWrite(ledS,LOW); //Apaga el LED
   }
 }

_005_LecturaSerieEntDig



Video _005

  • Esquema
E005.jpg
Lectura serie de una entrada digital a través del Monitor serial.
Vamos a leer la entrada digital del ejemplo anterior y mostrar en la pantalla del PC el estado del pulsador a través de mensajes que van apareciendo en el monitor serial. Los mensajes correspondientes al proceso del vídeo son los que vemos seguidamente.
E005Serial.jpg
  • Código
int pulsador=2; //Pin donde se encuentra el pulsador
//Configuraciones
void setup()
{
  pinMode(pulsador,INPUT); //Configurar el pulsador como entrada
  Serial.begin(9600); //Inicialización de la comunicación serie
}
void loop()
{
  //Guardamos en una variable entera el valor del pulsador
  int estadopulsador = digitalRead(pulsador);
  if (estadopulsador==1)// No esta pulsado
  {
    Serial.println("Pulsador NO accionado"); //Escribe en el Monitor serial
  }
  else // Pulsado
  {
    Serial.println("Pulsador accionado"); //Escribe en el Monitor serial
  }
  delay(1000); //Retardo para la visualización el Monitor serial
}

_006_ LecturaSerieEntAnalogica



Video _006

  • Esquema
E006.jpg

Leemos una entrada analógica mostrando por el Monitor serial el valor correspondiente a la lectura de la resistencia variable. El estado en el PC lo vemos en la imagen siguiente.
E006Serial.jpg
  • Código
void setup()
{
  Serial.begin(9600); //Inicialización de la comunicación serie
}
void loop()
{
int lectura= analogRead(A0);//Guarda el valor del potenciómetro (entre 0 y 1023)
Serial.println("Resistencia ajustada a:"); //Imprime en Monitor serial la cadena
Serial.println(lectura); //Imprime en Monitor serial el valor de la variable
delay(3000);//Retardo para la visualización de datos en Monitor serial
}

_007_ControlAnalogLumLED



Video _007

  • Esquema
E007.jpg
Graduar la luminosidad de un LED en función de la lectura analógica realizada de una resistencia variable.
El valor a escribir debe estar entre 0 y 255 y el valor que vamos a leer está entre 0 y 1023 por lo que debemos realizar un ajuste o escalado de valores. Esto se realiza fácilmente mediante map(), su sintaxis es: map(value, fromLow, fromHigh, toLow, toHigh). Adapta o mapea un número de un rango de valores a otro rango asignando fromLow a toLow, el valor fromHigh a tohigh, y valores intermedios de un rango a valores intermedios del nuevo rango.
  • Código
int Pin9 = 9; //Nombramos Pin 9
void setup() //Configuraciones
{
  pinMode(Pin9, OUTPUT); //Configurar el pin 9 como salida
}
void loop() //Bucle infinito
{
  int LecturaAnalogica = analogRead(0); //Guardamos en variable la lectura analógica
  LecturaAnalogica = map(LecturaAnalogica, 0, 1023, 0, 255); //Mapeamos la variable
  analogWrite(Pin9, LecturaAnalogica);//Escribimos en valor en el LED
}

_008_ControlLumLED_LDR



Video _008

  • Esquema
E008.jpg

Controlamos la luminosidad de un diodo LED con la técnica PWM a partir de la luminosidad recibida por una fotocélula o LDR. Los resultados que se muestran en el Monitor serial son:
E008Serial.jpg
Los valores menores corresponden al máximo de iluminación
  • Código
void setup() // Configuraciones
{
Serial.begin(9600); //Inicializa comunicación serie
pinMode(9,OUTPUT); //Configurar el pin 9 como salida
}
void loop()
{
int LDR = analogRead(A0); //Guarda valor lectura analógica LDR
int adapta = 900 - LDR; //Adaptacion valor lectura
if ( adapta < 0) //Valor absoluto
adapta = adapta * -1;
Serial.print("Lectura LDR: "); //Mostrar en Monitor
Serial.print(LDR);
Serial.println("");
Serial.print("Adaptacion valor lectura LDR: ");
Serial.print(adapta);
Serial.println("");
analogWrite(9, adapta); //Escritura PWM en LED
delay(1000);
}


_009_GenerandoTonos



Video _009

  • Esquema
E009.jpg

Generación de tonos audibles en un buzzer variando la frecuencia mediante el ajuste de una resistencia variable.
Usaremos la función tone(), cuya sintaxis es: tone(pin, frequency, duration), siendo pin la patilla donde se conecta el buzzer, frequency es la frecuencia en Hz y duration es la duración del tono.
  • Código

int Pinbuzzer = 9;  //Declara Pin conexion buzzer
int PinVar = 0;    //Declara Pin de la resistencia variable
void setup()
{
}
void loop()
{
  int Rvar = analogRead(PinVar); //Valor Rvar
  int frecuencia = map(Rvar,0,1023,100,5000); //Mapeamos valores leidos
  int duracion = 250;
  tone(Pinbuzzer, frecuencia, duracion);
  delay(100);
}


_010_ControlLED_RGB



Video 010

  • Esquema
E010.jpg

Se trata de poner en funcionamiento un LED RGB de ánodo común haciendo cambios automáticos de un color a otro mediante bucles for.
Introducimos la directiva #define y describimos este tipo de LEDs.
Directiva #defineSu sintaxis general es: #DEFINE constantName value
Se utiliza simplemente para reemplazar el identificador (constantName) con value. Por ejemplo, # define ledPin 3 hará que el compilador reemplace
cualquier aparición de ledPin con el valor 3 en tiempo de compilación.

Nunca se pone punto y coma después de la instrucción #define.

Diodos LEDs RGB

La configuración de pines de un dispositivo de ánodo común es como el que vemos en la figura.

E010REGAC.jpg

El pin 2 debemos llevarlo a positivo y cada diodo con su resistencia a polarización a negativo.
La configuración para un cátodo común es:
E010REGCC.jpg

Ahora el pin 2 debe ir a 0V y cada diodo con su resistencia a positivo.
  • Código

#define Rojo 5
#define Verde 6
#define Azul 3
void setup() { //Configuraciones. Pines 3, 5 y 6 como salida
  pinMode(Rojo, OUTPUT);
  pinMode(Verde, OUTPUT);
  pinMode(Azul, OUTPUT);
}
void loop() {
  int red, green, blue; //Variables bucles color
   //Bucle cambio azul a violeta
  for (red = 0; red < 256; red++) {
    analogWrite(Rojo, red);
    delay(5);
  }
  //Bucle cambio violeta a rojo
  for (blue = 255; blue > 0; blue--) {
    analogWrite(Azul, blue);
    delay(5);
  }
  //Bucle cambio rojo a amarillo
  for (green = 0; green < 256; green++) {
    analogWrite(Verde, green);
    delay(5);
  }
  //Bucle cambio amarillo a verde
  for (red = 255; red > 0; red--) {
    analogWrite(Rojo, red);
    delay(5);
  }
  //Bucle cambio verde a azul
  for (blue = 0; blue < 256; blue++) {
    analogWrite(Azul, blue);
    delay(5);
  }
  //Bucle cambio cian a azul
  for (green = 255; green > 0; green--) {
    analogWrite(Verde, green);
    delay(5);
  }
}

Otros ejemplos

No será habitual, pero aquí os pondré ejemplos de uso:
Reloj en tiempo real DS1302.



Plantilla

_xxx_aaa


Video _xxx


  • Esquema

Descripción breve y explicaciones
  • Código
Copiamos el código en el Widget Insert Source Code

Repositorio


Los ficheros se pueden encontrar en el siguiente repositorio:

Realizado por


  • Federico Coca
  • Francisco López

Herramientas de Software Libre